
/*
 * app.js
 * Copyright (C) 2020 2020-11-11 15:20 kalipy <kalipy@debian>
 *
 * Distributed under terms of the MIT license.
 */

const app = require('express')();
const server = require('http').createServer(app);
const io = require('socket.io')(server);
var exec = require('child_process').execFile;
var exec_py = require('child_process').exec
var fs = require('fs')
const request = require('request')

var SerialPort = require('serialport')
//Opening a Port
var serialPort = new SerialPort('/dev/ttyACM0', {
  //波特率，可在设备管理器中对应端口的属性中查看
  baudRate : 9600,
  autoOpen:false
})

//引入上传模块
let multer = require('multer')
//配置上传对象
let upload = multer({dest:"/home/kalipy/"})

server.listen(3000, () => {
  console.log('服务器启动成功')
});

app.get('/', function(req, res) {
  res.sendFile(__dirname + '/index.html')
})

app.get('/takePicture', async function(req, res) {
  console.log("paizao_with_adb before..");
  await paizao_with_adb()
  console.log("paizao_with_adb after..");
  //调用人脸识别
  console.log("checking_and_matchVerify before..");
  let matchRes= await checking_and_matchVerify()
  console.log("checking_and_matchVerify after..");
  console.log(matchRes);
  res.json({
    matchRes
  })
  console.log("/takePicture end..");
})


io.on('connection',socket => {
  serialPort.open(function(err) {
    if (serialPort.isOpen == false) {
      socket.emit("error", "error,开发板的串口线未与开发板连接!!")
      socket.emit("link", "连接失败!!")
      console.log('err:', err)
    } else {
      socket.emit("link", "连接成功!!")
    }
  })

  console.log('新用户连接了')
  //监听客户端传递给串口的数据，数据为data
  socket.on('sendmsg',async function (data) {
    console.log("sendmsg:" + data)
    //把客户端传过来的数据写给串口
    writeToSerial(data);
//    if (data == "take a picture") {//客户端给串口发了"take a picture"表示要进行人脸识别
//      await paizao_with_adb()
//      //调用人脸识别
//      let matchRes= await checking_and_matchVerify()
//      console.log(matchRes);
//    }
  })

  socket.on('downloadhex', data => {
    console.log(data)
    downloadHex(socket)
  })

  socket.on('watch', data => {
    console.log(data)
    socket.emit("watch", "此功能正在开发中..")
  })
})

//下载hex到开发板
function downloadHex(socket) {
  exec('./stm32fxx_telnet_start.sh',{encoding:'utf8'},function (err,stdout,stderr){
    if (err){
      console.log(err);
      //发送数据到客户端
      socket.emit('downloadfail','下载失败！')
      return;
    }
    console.log(stdout)
    //发送数据到客户端
    socket.emit('downloadok',"下载成功");
  });
}

//调用adb.py拍照
function paizao_with_adb() {
  return new Promise((resolve, reject)=>{
    console.log("paizao_with_adb Promise..")
    //打开手机给开发板拍照
    exec_py('python3 adb.py',{encoding:'utf8'},function (err,stdout,stderr){
      if (err){
        console.log("err:"+err);
        //发送数据到客户端
        //socket.emit('downloadfail','下载失败！')
        reject(err);
      }
      console.log("ok:"+stdout)
      resolve("ok");
      //拍照成功，把照片发给客户端

      //发送数据到客户端
      //socket.emit('downloadok',"下载成功");
    });
  })
}

//上传文件
app.post('/imgUpload',upload.single('imgfile'),function(req,res){
  console.log(req.file)
  //因为直接上传的文件为随机字符名字，我们想要重新命名
  let oldPath = req.file.destination+"/"+req.file.filename
  let newPath = req.file.destination+"/"+"33.hex"
  fs.rename(oldPath, newPath, ()=>{
    console.log("改名成功")
  })
  res.json({
    state:'ok',
  })
})

//下载文件
app.get('/imgDownload', async function(req, res) {
  await paizao_with_adb()
  let localPath = "./1.jpg"
  res.download(localPath)
});

//延时
function sleepPromise(ms) {
  return new Promise(resolve => setTimeout(resolve, ms))
}

//写串口
function writeToSerial(data) {
  console.log("串口data:" + data)
  serialPort.write(data, function(error, data) {
    if (error) {
      console.log(error)
    } else {
      console.log("result:"+data)
    }
  })
}

//指令监听
serialPort.on('data',function (data) {
  console.log('data received: '+data)
})
//错误监听
serialPort.on('error',function (error) {
  console.log('error: '+error)
})

//-------------------------人脸识别模块-------------------------
function checking_and_matchVerify() {
  return new Promise((resolve, reject)=>{
    console.log("checking_and_matchVerify Promise..")

    let bitmap = fs.readFileSync('./1.jpg');
    let base64str = Buffer.from(bitmap, 'binary').toString('base64'); // base64编码
    //console.log(base64str);

    var url ="https://aip.baidubce.com/rest/2.0/face/v3/detect?access_token=24.59c71e38d1e69977d54309f024730e98.2592000.1610546185.282335-23152618" 
    var formData = {
      image: base64str,
      image_type:"BASE64",
      face_field:"faceshape,facetype"
    }
    request.post({url:url, formData: formData},async function (error, response, body) {
      if (error) {
        console.log(error)
      } else {
        //console.log("body:" + body)
        var body = JSON.parse(body);
        if (body.error_msg == "SUCCESS") {
          face_token = body.result.face_list[0].face_token;
          console.log("face_token:" + body.result.face_list[0].face_token)
          console.log("match_verify before..")
          let res = await match_verify(face_token)
          console.log("match_verify after..")
          resolve(res);//一定要有resolve或reject，不然阻塞在本Promise中
        }
      }
    })
  })
}

function match_verify(face_id) {
  return new Promise((resolve, reject)=>{
    console.log("match_verify Promise..")
    var url2 ="https://aip.baidubce.com/rest/2.0/face/v3/match?access_token=24.59c71e38d1e69977d54309f024730e98.2592000.1610546185.282335-23152618"
    var formData = [
      {
        image: face_id,
        image_type:"FACE_TOKEN"
      },
      {
        //来自b.jpg 即基准图片
        image: "41d5e0a556e67424c4d375181264e542",
        image_type:"FACE_TOKEN"
      }
    ]

    /*
 application/json (JSON表单)
 */
    request({
      url: url2,
      method: "POST",
      json: true,
      headers: {
        "content-type": "application/json",
      },
      //body: JSON.stringify(formData)
      body: formData
    }, function(error, response, body) {
      if (!error) {
        if (body.error_msg == "SUCCESS") {
          console.log(body.result.score)
          resolve(body);//一定要有resolve或reject，不然阻塞在本Promise中
        }
      }
    })
  })
}

